home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 May (DVD) / Macworld Resource DVD May 2003.toast / Data / Software / Bonus / Programming / revolutionosx.sit / Revolution 1.1.1 / External SDK / XCmdGlue.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-12-21  |  19.6 KB  |  834 lines  |  [????/????]

  1. /********************************************/
  2. /*    Copyright 1997 MetaCard Corporation   */
  3. /*    All Rights Reserved                   */
  4. /********************************************/
  5. /*
  6.  * Support routines for MetaCard external commands and functions
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12.  
  13. #ifdef MACOS  
  14.     #include <A4Stuff.h>
  15. #else
  16. #include <sys/types.h>
  17. #endif //MACOS
  18.  
  19. #ifdef X11
  20. #include <values.h>
  21. #ifdef SELECT
  22. #ifndef LINUX
  23. /* some systems don't have select.h and/or stream.h.  If yours doesn't
  24.    delete the offending #include */
  25. #include <sys/select.h>
  26. #include <sys/stream.h>
  27. #endif //LINUX
  28. #else
  29. #include <poll.h>
  30. #endif //SELECT
  31. #include <X11/Xlib.h>
  32. #include <X11/Xutil.h>
  33. #include <X11/Xos.h>
  34. #include <X11/Xatom.h>
  35. #elif defined WIN32
  36. #endif //X11
  37.  
  38. #include "XCmdGlue.h"
  39. #include "XCmdName.h"
  40.  
  41. #define XATOMSIZE 16
  42. #define XINTSTRSIZE 16
  43. #define XMAXPACK 65535
  44.  
  45. int MCidleRate = 200;
  46.  
  47. #if defined WIN32 || defined MACOS
  48. static XCB *cbs;
  49. static DELETER deleter;
  50. extern char Xname[];
  51. static char *callback(int id, const char *arg1, const char *arg2,
  52.               const char *arg3, int *retval);
  53. static void freer(char *data);
  54.  
  55.  
  56. #ifdef MACOS
  57. // dummy SIOUX calls
  58. void RemoveConsole(void);
  59. long WriteCharsToConsole(char *buffer, long n);
  60. long ReadCharsFromConsole(char *buffer, long n);
  61. short InstallConsole(short fd);
  62. void RemoveConsole(void) { }
  63. long WriteCharsToConsole(char *buffer, long n) { return n; }
  64. long ReadCharsFromConsole(char *buffer, long n) { return 0; }
  65. short InstallConsole(short fd) { return 0; }
  66.  
  67. /*__procinfo, a global variable is of ProcInfoType informs the Mixed Mode Manager of the *
  68.  *parameters and return type of your main entry point (main in this case).               */
  69.  
  70. ProcInfoType __procinfo = kThinkCStackBased
  71.                  | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(XCB*)))
  72.          | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DELETER)))
  73.          | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(char**)))
  74.          | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Xternal**)))
  75.          | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(DELETER*)));
  76.  
  77. #endif //MACOS
  78.          
  79. /* Called from MC engine */
  80.  
  81. void getXtable(XCB icbs[], DELETER d, const char **name,
  82.            Xternal **table, DELETER *f)
  83. {
  84. #ifdef MACOS
  85. #ifndef __powerc
  86. #if !TARGET_API_MAC_CARBON
  87.       long oldA4 = SetCurrentA4();
  88.   #endif //not carbon
  89. #endif //_powerpc
  90. #endif //MACOS
  91.   cbs = icbs;
  92.   deleter = d;
  93.   *name = Xname;
  94.   *table = Xtable;
  95.   *f = freer; 
  96. #ifdef MACOS
  97. #ifndef __powerc
  98. #if !TARGET_API_MAC_CARBON
  99.   SetA4(oldA4);
  100.  #endif //not carbon
  101. #endif //_powerpc
  102. #endif //MACOS
  103. }
  104.  
  105. static char *callback(int id, const char *arg1, const char *arg2,
  106.               const char *arg3, int *retval)
  107. {
  108.   char *data = (*cbs[id])(arg1, arg2, arg3, retval);
  109.   char *retstring = NULL;
  110.   if (data != NULL)
  111.     retstring = istrdup(data);
  112.   (*deleter)(data);
  113.   return retstring;
  114. }
  115.  
  116. static void freer(char *data)
  117. {
  118.   free(data);
  119. }
  120.  
  121. static char *getstatus()
  122. {
  123.   return istrdup("ready");
  124. }
  125.  
  126. void X_set_idle_handler(void (*function)())
  127. {
  128.   (*cbs[MC_ID])((char *)function, NULL, NULL, NULL);
  129. }
  130.  
  131. void X_set_idle_rate(int newrate)
  132. {
  133.   (*cbs[MC_REGISTER])((char *)newrate, NULL, NULL, NULL);
  134. }
  135.  
  136. /********** X11 code *****************************/
  137. #elif defined X11
  138. static char *XCAtomNames[MC_NUM_ATOMS] = {
  139.   MC_ID_STRING,
  140.   MC_ABORT_STRING,
  141.   MC_REGISTER_STRING,
  142.   MC_CARD_MESSAGE_STRING,
  143.   MC_MC_MESSAGE_STRING,
  144.   MC_EVAL_EXPRESSION_STRING,
  145.   MC_GET_GLOBAL_STRING,
  146.   MC_SET_GLOBAL_STRING,
  147.   MC_GET_FIELD_BY_NAME_STRING,
  148.   MC_GET_FIELD_BY_NUMBER_STRING,
  149.   MC_GET_FIELD_BY_ID_STRING,
  150.   MC_SET_FIELD_BY_NAME_STRING,
  151.   MC_SET_FIELD_BY_NUMBER_STRING,
  152.   MC_SET_FIELD_BY_ID_STRING,
  153.   MC_SHOW_IMAGE_BY_NAME_STRING,
  154.   MC_SHOW_IMAGE_BY_NUMBER_STRING,
  155.   MC_SHOW_IMAGE_BY_ID_STRING,
  156.   MC_GET_VARIABLE_STRING,
  157.   MC_SET_VARIABLE_STRING,
  158.   MC_GET_VARIABLE_EX_STRING,
  159.   MC_SET_VARIABLE_EX_STRING,
  160.   MC_GET_ARRAY_STRING,
  161.   MC_SET_ARRAY_STRING
  162. };
  163.  
  164. Window MCwin = 0;
  165. Display *MCdpy;
  166. Bool MCQuit;
  167. static Xternal *XternalTable;
  168. static Atom XCAtoms[MC_NUM_ATOMS];
  169. static Atom mcatom;
  170. static Atom idatom = None;
  171. static int ncalls = 0;
  172. static int curxid = 0;
  173. static char **binbuffers = NULL;
  174. static int nbinbuffers = 0;
  175. #ifdef __STDC__
  176. static void (*idlefunc)();
  177. static Bool (*prefunc)(XEvent *e);
  178. static void (*postfunc)(XEvent *e);
  179. #ifdef SELECT
  180. static int (*selectfunc)(int n, fd_set *r, fd_set *w, 
  181.              fd_set *e, struct timeval *t);
  182. #else //SELECT
  183. static int (*pollfunc)(struct pollfd fd[], int nfds, int timeout);
  184. #endif //SELECT
  185. #else //_STDC_
  186. static void (*idlefunc)();
  187. static Bool (*prefunc)();
  188. static void (*postfunc)();
  189. #ifdef SELECT
  190. static int (*selectfunc)();
  191. #else //SELECT
  192. static int (*pollfunc)();
  193. #endif //SELECT
  194. #endif //_STDC_
  195.  
  196. #ifdef __STDC__
  197. static char *send_message(Atom atom, const char *arg1, const char *arg2,
  198.               const char *arg3, Bool pass, Bool error, int *retval);
  199.               static int xencodebinarg(MCstring *arg,char *binstring);
  200.               static int xdecodebinarg(char *binstring,MCstring *binaryarg);
  201.               static int xencodearray(MCarray *arg,char *destptr);
  202.               static int xdecodearray(char *binstring,MCarray *barray);
  203.               static void add_to_bufferlist(char *tdata);
  204.               static void clear_bufferlist();
  205.               
  206. #else
  207. static char *send_message();
  208.  static int xencodebinarg();
  209.  static int xdecodebinarg();
  210.  static int xencodearray();
  211.  static int xdecodearray();
  212.  static void add_to_bufferlist();
  213.  static void clear_bufferlist();
  214. #endif
  215.  
  216. #ifdef __STDC__
  217. static char *dispatch_event(XEvent *event, Atom replyatom, int *retval)
  218. #else
  219. static char *dispatch_event(event, replyatom, retval)
  220. XEvent *event;
  221. Atom replyatom;
  222. int *retval;
  223. #endif
  224. {
  225.   int i;
  226.   Atom type;
  227.   int format;
  228.   unsigned long nitems, extra;
  229.   unsigned char *uprop;
  230.   char *prop;
  231.   char *replystring = NULL;
  232.  
  233.   XPropertyEvent *pevent = (XPropertyEvent *)event;
  234.   switch (event->type) {
  235.   case PropertyNotify:
  236.     if (pevent->state != PropertyNewValue)
  237.       break;
  238.     if (pevent->atom == replyatom) {
  239.       char *sptr;
  240.       XGetWindowProperty(MCdpy, MCwin, pevent->atom, 0, XMAXPACK,
  241.              False, XA_STRING, &type, &format,
  242.              &nitems, &extra, &uprop);
  243.       prop = (char *)uprop;
  244.       if (atol(prop) != (long)idatom) {
  245.     XFree(prop);
  246.     break;
  247.       }
  248.       sptr = &prop[strlen(prop) + 1];
  249.       sptr += strlen(sptr) + 1;
  250.       *retval = atoi(sptr);
  251.       sptr += strlen(sptr) + 1;
  252.          if (curxid == MC_GET_VARIABLE_EX || curxid == MC_GET_ARRAY){
  253. /* don't bother to parse of calculate size use nitems */
  254.     int length = sptr - prop;
  255.     replystring = malloc(nitems - length);
  256.     memcpy(replystring,sptr,nitems - length);
  257.       }
  258.       else {
  259.     replystring = malloc(strlen(sptr) + 1);
  260.     strcpy(replystring, sptr);
  261.       }
  262.       XFree(prop);
  263.       break;
  264.     }
  265.     for (i = 0 ; i < ncalls ; i++)
  266.       if (pevent->atom == XternalTable[i].atom) {
  267.     char **strings;
  268.     int length = 0;
  269.     int nstrings = 0;
  270.     Bool pass = False;
  271.     Bool error = False;
  272.     strings = (char **)malloc(sizeof(char *));
  273.     XGetWindowProperty(MCdpy, MCwin, pevent->atom, 0,
  274.                XMAXPACK, False, XA_STRING, &type,
  275.                &format, &nitems, &extra, &uprop);
  276.     prop = (char *)uprop;
  277.     if (atol(prop) != (long)idatom) {
  278.       XFree(prop);
  279.       break;
  280.     }
  281.     while (length < nitems) {
  282.       nstrings++;
  283.       strings = (char **)realloc(strings, nstrings * sizeof(char *));
  284.       strings[nstrings - 1] = &prop[length];
  285.       length += strlen(strings[nstrings - 1]) + 1;
  286.     }
  287.     if (XternalTable[i].call != NULL) {
  288.       (*XternalTable[i].call)(&strings[2], nstrings - 2,
  289.                 &replystring, &pass, &error);
  290.       send_message(XternalTable[i].atom, replystring, NULL, NULL,
  291.                pass, error, NULL);
  292.                clear_bufferlist();
  293.       if (replystring != NULL) {
  294.         free(replystring);
  295.         replystring = NULL;
  296.       }
  297.     }
  298.     free(strings);
  299.     XFree(prop);
  300.       }
  301.     break;
  302.   case DestroyNotify:
  303.     MCQuit = True;
  304.     break;
  305.   default:
  306.     break;
  307.   }
  308.   return replystring;
  309. }
  310.  
  311. #ifdef __STDC__
  312. static char *send_message(Atom atom, const char *arg1, const char *arg2,
  313.               const char *arg3, Bool pass, Bool error, int *retval)
  314. #else
  315. static char *send_message(atom, arg1, arg2, arg3, pass, error, retval)
  316. Atom atom;
  317. char *arg1;
  318. char *arg2;
  319. char *arg3;
  320. Bool pass;
  321. Bool error;
  322. int *retval;
  323. #endif
  324. {
  325.   int i = 0;
  326.   int length = XATOMSIZE * 2 + 7;
  327.   char *send;
  328.   char *replystring = NULL;
  329.   
  330.   if (arg1 != NULL)
  331.     length += strlen(arg1);
  332.   if (arg2 != NULL)
  333.     length += strlen(arg2);
  334.   if (arg3 != NULL){
  335.     if (curxid == MC_SET_VARIABLE_EX) {
  336.       MCstring *binaryarg = (MCstring *)arg3;
  337.       length += xencodebinarg(binaryarg,NULL);
  338.     }
  339.     else if (curxid == MC_SET_ARRAY) {
  340.       MCarray *barray = (MCarray *)arg3;
  341.       length += xencodearray(barray,NULL);
  342.     }
  343.     else
  344.       length += strlen(arg3);
  345.   }
  346.   send = malloc(length);
  347.   sprintf(&send[i], "%ld", mcatom);
  348.   i += strlen(&send[i]) + 1;
  349.   sprintf(&send[i], "%ld", idatom);
  350.   i += strlen(&send[i]) + 1;
  351.   sprintf(&send[i], "%d", (int)(pass != 0));
  352.   i += strlen(&send[i]) + 1;
  353.   sprintf(&send[i], "%d", (int)(error != 0));
  354.   if (arg1 != NULL) {
  355.     i += strlen(&send[i]) + 1;
  356.     sprintf(&send[i], "%s", arg1);
  357.   }
  358.   if (arg2 != NULL) {
  359.     i += strlen(&send[i]) + 1;
  360.     sprintf(&send[i], "%s", arg2);
  361.   }
  362.  if (arg3 != NULL) {
  363.     i += strlen(&send[i]) + 1;
  364.     if (curxid == MC_SET_VARIABLE_EX) {
  365.       MCstring *binaryarg = (MCstring *)arg3;
  366.       int length = xencodebinarg(binaryarg,&send[i]);
  367.       i += length;
  368.     }
  369.     else if (curxid == MC_SET_ARRAY) {
  370.       MCarray *barray = (MCarray *)arg3;
  371.       int length = xencodearray(barray,&send[i]);
  372.       i+=length;
  373.     }
  374.     else {
  375.       sprintf(&send[i], "%s", arg3);
  376.       i += strlen(&send[i]) + 1;
  377.     }
  378.   }
  379.   else
  380.     i += strlen(&send[i]) + 1;
  381.   XChangeProperty(MCdpy, MCwin, atom, XA_STRING, 8,
  382.           PropModeReplace, (unsigned char *)send, i);
  383.   free(send);
  384.   if (retval != NULL) {
  385.     while (replystring == NULL && !MCQuit) {
  386.       XEvent event;
  387.       if (XCheckTypedWindowEvent(MCdpy, MCwin, PropertyNotify, &event))
  388.     replystring = dispatch_event(&event, atom, retval);
  389.       else
  390.     XSync(MCdpy, False);
  391.     }
  392.   }
  393.    if (curxid == MC_GET_VARIABLE_EX){
  394.       MCstring *bstring = (MCstring *)arg3;
  395.       xdecodebinarg(replystring,bstring);
  396.       add_to_bufferlist(replystring);
  397.     }
  398.   else if (curxid == MC_GET_ARRAY){
  399.     MCarray *barray = (MCarray *)arg3;
  400.     xdecodearray(replystring, barray);
  401.     add_to_bufferlist(replystring);
  402.   } 
  403.   curxid = 0;    
  404.   return replystring;
  405. }
  406.  
  407. #ifdef __STDC__
  408. static void register_functions(Xternal *table, char *name)
  409. #else
  410. static void register_functions(table, name)
  411. Xternal *table;
  412. char *name;
  413. #endif
  414. {
  415.   int regi = 0;
  416.   char *regstring;
  417.   regstring = malloc(XATOMSIZE * 2 + 4);
  418.   
  419.   XternalTable = table;
  420.   mcatom = XInternAtom(MCdpy, XCAtomNames[MC_ID], False);
  421.   idatom = XInternAtom(MCdpy, name, False);
  422.   
  423.   sprintf(®string[regi], "%ld", mcatom);
  424.   regi += strlen(®string[regi]) + 1;
  425.   sprintf(®string[regi], "%ld", idatom);
  426.   regi += strlen(®string[regi]) + 1;
  427.   sprintf(®string[regi], "%d", 0);
  428.   regi += strlen(®string[regi]) + 1;
  429.   sprintf(®string[regi], "%d", 0);
  430.   regi += strlen(®string[regi]) + 1;
  431.   while (strlen(XternalTable[ncalls].name) != 0) {
  432.     XternalTable[ncalls].atom = XInternAtom(MCdpy,
  433.                         XternalTable[ncalls].name, False);
  434.     regstring = realloc(regstring, regi + strlen(XternalTable[ncalls].name)
  435.             + strlen(XternalTable[ncalls].type) + 2);
  436.     sprintf(®string[regi], "%s", XternalTable[ncalls].name);
  437.     regi += strlen(®string[regi]) + 1;
  438.     sprintf(®string[regi], "%s", XternalTable[ncalls].type);
  439.     regi += strlen(®string[regi]) + 1;
  440.     ncalls++;
  441.   }
  442.   XChangeProperty(MCdpy, MCwin,
  443.           XInternAtom(MCdpy, XCAtomNames[MC_REGISTER], False),
  444.           XA_STRING, 8, PropModeReplace,
  445.           (unsigned char *)regstring, regi);
  446.   free(regstring);
  447. }
  448.  
  449. #ifdef __STDC
  450. static char *callback(int id, const char *arg1, const char *arg2,
  451.               const char *arg3, int *retval)
  452. #else
  453. static char *callback (id, arg1, arg2, arg3, retval)
  454. int id;
  455. char *arg1;
  456. char *arg2;
  457. char *arg3;
  458. int *retval;
  459. #endif
  460. {
  461.   if (XCAtoms[id] == None)
  462.     XCAtoms[id] = XInternAtom(MCdpy, XCAtomNames[id], False);
  463.       curxid = id;
  464.   return send_message(XCAtoms[id], arg1, arg2, arg3, False, False, retval);
  465. }
  466.  
  467. static char *getstatus()
  468. {
  469.   Atom type;
  470.   int format;
  471.   unsigned long nitems, extra;
  472.   unsigned char *uprop;
  473.   char *newprop;
  474.   Atom statatom = XInternAtom(MCdpy, MC_GET_MC_STATUS_STRING, False);
  475.   XGetWindowProperty(MCdpy, MCwin, statatom, 0,
  476.              XMAXPACK, False, XA_STRING, &type,
  477.              &format, &nitems, &extra, &uprop);
  478.   if (type == None)
  479.     return istrdup("startup");
  480.   newprop = (char *)uprop;
  481.   newprop = istrdup(newprop);
  482.   XFree(uprop);
  483.   return newprop;
  484. }
  485.  
  486. #ifdef __STDC__
  487. Bool X_init(int argc, char *argv[], char *envp[], Xternal *table,
  488.         char *name)
  489. #else
  490. Bool X_init(argc, argv, envp, table, name)
  491. int argc;
  492. char *argv[];
  493. char *envp[];
  494. Xternal *table;
  495. char *name;
  496. #endif
  497. {
  498.   int i;
  499.   char *dname = NULL;
  500.   
  501.   for (i = 1; i < argc; i++) {
  502.     if (strncmp(argv[i], "-d", 2) == 0) {
  503.       if (++i >= argc || *argv[i] == '-') {
  504.     fprintf(stderr, "%s: bad display name\n", argv[0]);
  505.     return False;
  506.       }
  507.       dname = argv[i];
  508.       continue;
  509.     }
  510.     if (strncmp(argv[i], "-w", 2) == 0) {
  511.       if (++i >= argc || *argv[i] == '-' || 
  512.       (MCwin = (Window)atol(argv[i])) == 0) {
  513.     fprintf(stderr, "%s: bad window id\n", argv[0]);
  514.     return False;
  515.       }
  516.       continue;
  517.     }
  518.     fprintf(stderr, "%s: argument <%s> ignored\n", argv[0], argv[i]);
  519.   }
  520.   
  521.   if (MCwin == 0) {
  522.     fprintf(stderr, "Usage: %s [-display displayname] -w windowid\n",
  523.         argv[0]);
  524.     return False;
  525.   }
  526.   
  527.   if ((MCdpy = XOpenDisplay(dname)) == NULL) {
  528.     fprintf(stderr, "%s: Can't open display %s\n", argv[0], dname);
  529.     return False;
  530.   }
  531.   
  532.   register_functions(table, name);
  533.   
  534.   XSelectInput(MCdpy, MCwin, PropertyChangeMask | StructureNotifyMask);
  535.   return True;
  536. }
  537.  
  538. #ifdef __STDC__
  539. static Bool next_event(XEvent *event)
  540. #else
  541. static Bool next_event(event)
  542. XEvent *event;
  543. #endif
  544. {
  545.   if (!XPending(MCdpy) && (idlefunc != NULL
  546. #ifdef SELECT
  547.                || selectfunc != NULL)) {
  548.     struct timeval interval;
  549.     fd_set rmaskfd;
  550.     
  551.     interval.tv_sec = MCidleRate / 1000;
  552.     interval.tv_usec = MCidleRate % 1000 * 1000;
  553.     
  554.     FD_ZERO(&rmaskfd);
  555.     FD_SET(ConnectionNumber(MCdpy), &rmaskfd);
  556.     if (selectfunc != NULL) {
  557.       if (!(*selectfunc)(ConnectionNumber(MCdpy) + 1, &rmaskfd,
  558.              NULL, NULL, &interval) == 0)
  559.     return False;
  560.     }
  561.     else
  562.       if (select(ConnectionNumber(MCdpy) + 1, &rmaskfd,
  563.          NULL, NULL, &interval) == 0)
  564.     return False;
  565. #else //SELECT
  566.                || pollfunc != NULL)) {
  567.     struct pollfd fds[1];
  568.     fds[0].fd = ConnectionNumber(MCdpy);
  569.     fds[0].events = POLLIN;
  570.     if (pollfunc != NULL) {
  571.       if (!(*pollfunc)(fds, 1, MCidleRate))
  572.     return False;
  573.     }
  574.     else
  575.       if (!poll(fds, 1, MCidleRate))
  576.     return False;
  577. #endif //SELECT
  578.   }
  579.   XNextEvent(MCdpy, event);
  580.   return True;
  581. }
  582.  
  583. #ifdef __STDC__
  584. void X_set_idle_handler(void (*function)())
  585. #else
  586. void X_set_idle_handler(function)
  587. void (*function)();
  588. #endif
  589. {
  590.   idlefunc = function;
  591. }
  592.  
  593. #ifdef __STDC__
  594. void X_set_idle_rate(int newrate)
  595. #else
  596. void X_set_idle_rate(newrate)
  597. int newrate;
  598. #endif
  599. {
  600.   MCidleRate = newrate;
  601. }
  602.  
  603. #ifdef __STDC__
  604. void X_set_pre_xevent_handler(Bool (*function)(XEvent *e))
  605. #else
  606. void X_set_pre_xevent_handler(function)
  607. void (*function)();
  608. #endif
  609. {
  610.   prefunc = function;
  611. }
  612.  
  613. #ifdef __STDC__
  614. void X_set_post_xevent_handler(void (*function)(XEvent *e))
  615. #else
  616. void X_set_post_xevent_handler(function)
  617. void (*function)();
  618. #endif
  619. {
  620.   postfunc = function;
  621. }
  622.  
  623. #ifdef SELECT
  624. #ifdef __STDC__
  625. void X_set_select_handler(int (*function)(int n, fd_set *r, fd_set *w, 
  626.                       fd_set *e, struct timeval *t))
  627. #else //_STDC_
  628. void X_set_select_handler(function)
  629. void (*function)();
  630. #endif //_STDC_
  631. {
  632.   selectfunc = function;
  633. }
  634. #else //SELECT
  635. #ifdef __STDC__
  636. void X_set_poll_handler(int (*function)(struct pollfd fd[], 
  637.                     int nfds, int timeout))
  638. #else //_STDC_
  639. void X_set_poll_handler(function)
  640. void (*function)();
  641. #endif //_STDC_
  642. {
  643.   pollfunc = function;
  644. }
  645. #endif //SELECT
  646.  
  647. void X_main_loop()
  648. {
  649.   while (!MCQuit) {
  650.     XEvent event;
  651.     if (next_event(&event)) {
  652.       if (prefunc != NULL)
  653.     if (!(*prefunc)(&event))
  654.       continue;
  655.       dispatch_event(&event, 0, NULL);
  656.       if (postfunc != NULL)
  657.     (*postfunc)(&event);
  658.     }
  659.     else
  660.       if (idlefunc != NULL)
  661.     (*idlefunc)();
  662.   }
  663. }
  664.  
  665. int X_close()
  666. {  
  667.   XFlush(MCdpy);
  668.   XCloseDisplay(MCdpy);
  669.   return 0;
  670. }
  671.  
  672. #ifdef _STDC_
  673. static int xencodebinarg(MCstring *arg,char *binstring)
  674. #else
  675.      static int xencodebinarg(arg, binstring)
  676.      MCstring *arg;
  677.      char *binstring;
  678. #endif
  679. {
  680.   int length =0;
  681.   if (binstring == NULL)
  682.     return XINTSTRSIZE + arg->length;
  683.   sprintf(&binstring[length],"%d",arg->length);
  684.   length+=strlen(&binstring[length])+1;
  685.   if (arg->length != 0)
  686.   memcpy(&binstring[length],arg->sptr,arg->length);
  687.   length += arg->length;
  688.   return length;
  689. }
  690.  
  691. #ifdef __STDC__ 
  692. static int xdecodebinarg(char *binstring,MCstring *binaryarg)
  693. #else
  694. static int xdecodebinarg(binstring,binaryarg)
  695. char *binstring;
  696. MCstring *binaryarg;
  697. #endif
  698. {
  699.   int length;
  700.   binaryarg->length = atoi(binstring);
  701.   length = strlen(binstring)+1;
  702.   if (binaryarg->length != 0)
  703.     binaryarg->sptr = binstring+length;
  704.   else 
  705.     binaryarg->sptr = NULL;
  706.   length+=binaryarg->length;
  707.   return length;
  708. }
  709.  
  710. #ifdef _STDC_
  711. static int xencodearray(MCarray *arg,char *destptr)
  712. #else
  713. static int xencodearray(arg, destptr)
  714. MCarray *arg;
  715. char *destptr;
  716. #endif
  717. {
  718.   int length = 0;
  719.   int i;
  720.   if (destptr == NULL){
  721.     length += XINTSTRSIZE; //nelements
  722.     if (arg->strings != NULL && arg->nelements > 0){
  723.       for (i = 0; i < arg->nelements; i++)
  724.     length += xencodebinarg(&arg->strings[i],NULL);
  725.     }
  726.     else length += 1;
  727.     if (arg->keys != NULL && arg->nelements > 0){
  728.       for (i = 0; i < arg->nelements; i++){
  729.     if (arg->keys[i] != NULL)
  730.       length += strlen(arg->keys[i])+1;
  731.     else length += 1;
  732.       }
  733.     }
  734.     else length += 1;
  735.     return length;
  736.   }
  737.   sprintf(&destptr[length], "%d", arg->nelements);
  738.   length += strlen(&destptr[length]) + 1;
  739.   if (arg->strings != NULL &&  arg->nelements > 0){
  740.     for (i = 0; i < arg->nelements; i++)
  741.       length += xencodebinarg(&arg->strings[i],&destptr[length]);
  742.   }
  743.   else
  744.     destptr[length++] = '\0';
  745.   if (arg->keys != NULL && arg->nelements > 0){
  746.     for (i = 0; i < arg->nelements; i++){
  747.       if (arg->keys[i] != NULL){
  748.     sprintf(&destptr[length],"%s",arg->keys[i]);
  749.     length += strlen(&destptr[length])+1;
  750.       }
  751.       else
  752.     destptr[length++] = '\0';
  753.     }
  754.   }
  755.   else 
  756.     destptr[length++] = '\0';
  757.   return length;
  758. }
  759.  
  760. #ifdef __STDC__ 
  761. static int xdecodearray(char *binstring,MCarray *barray)
  762. #else
  763.      static int xdecodearray(binstring,barray)
  764.      char *binstring;
  765.      MCarray *barray;
  766. #endif
  767. {
  768.   int length = 0;
  769.   int i;
  770.   barray->nelements =  atoi(&binstring[length]);
  771.   length += strlen(&binstring[length])+1;
  772.   if (barray->strings == NULL)
  773.     return 0;
  774.   if (binstring[length] != '\0'){
  775.     for (i = 0; i < barray->nelements; i++)
  776.       length += xdecodebinarg(&binstring[length],&barray->strings[i]);
  777.   }
  778.   else {
  779.     barray->strings = NULL;
  780.     length++;
  781.   }
  782.   if (binstring[length] != '\0'){
  783.     for (i = 0; i < barray->nelements; i++){
  784.       barray->keys[i] = &binstring[length];
  785.       if (*(barray->keys[i]) == '\0')
  786.     barray->keys[i] = NULL;
  787.       length += strlen(&binstring[length])+1;
  788.     }
  789.   }
  790.   else {
  791.     barray->keys = NULL;
  792.     length++;
  793.   }
  794.   return length;
  795. }
  796.  
  797. #ifdef _STDC_
  798. static void add_to_bufferlist(char *tdata)
  799. #else
  800. static void add_to_bufferlist(tdata)
  801. char *tdata;
  802. #endif
  803. {
  804. if (nbinbuffers == 0)
  805. binbuffers = (char **)malloc(sizeof(char *)); 
  806. else
  807.  binbuffers = (char **)realloc(binbuffers, (nbinbuffers + 1) * sizeof(char *));
  808. binbuffers[nbinbuffers] = tdata;
  809.  nbinbuffers++;
  810. }
  811.  
  812. #ifdef _STDC_
  813. static void clear_bufferlist()
  814. #else
  815. static void clear_bufferlist()
  816. #endif
  817. {
  818. if (binbuffers != NULL) {
  819. int i;
  820. for (i = 0; i < nbinbuffers ; i++)
  821. free(binbuffers[i]);
  822. free(binbuffers);
  823. }
  824.  nbinbuffers = 0;
  825. binbuffers = NULL;
  826. }
  827.  
  828.  
  829. #endif //X11
  830.  
  831. #include "XCmdFunc.c"
  832.  
  833.  
  834.